package guiWindows;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.lang.reflect.Array;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.DefaultListModel;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.MenuKeyEvent;
import javax.swing.event.MenuKeyListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultCaret;
import javax.swing.text.JTextComponent;

import objectsDiagram.Task;

public class PanelArea extends JPanel{
	private static final long serialVersionUID = -1;
	private JLabel newLabelArea;
	private JTextArea newArea = new JTextArea();
	private JCheckBox newCheckArea = new JCheckBox();
	private JScrollPane scrollArea;
	private Vector<Task> vectorTask;
	private JDialog popupMenu;
	private JMenuItem menuItemStart;
	private JMenuItem menuItemEnd;
	private JPopupMenu popupMenuMode;
	private JPanel panel;
	private JList verticalTask;
	private JScrollPane scrollPaneMenu;
	private DefaultListModel model;

	public PanelArea(int numberFormula, Vector<Task> newVectorTask){
		this.vectorTask = newVectorTask;
		this.newLabelArea  = new JLabel(""+numberFormula);
		this.newArea.setMinimumSize(new Dimension(100,50));
		this.newCheckArea.setMinimumSize(new Dimension(100,50));
		this.newLabelArea.setMinimumSize(new Dimension(100,50));
		this.scrollArea = new JScrollPane(newArea);
		this.setLayout(new BorderLayout());
		this.add(newLabelArea,BorderLayout.WEST);
		this.add(scrollArea,BorderLayout.CENTER);
		this.add(newCheckArea,BorderLayout.EAST);
		this.newArea.setLineWrap(true);
		this.newArea.setDragEnabled(true);
		this.newArea.setWrapStyleWord(true);
		popupMenuMode = new JPopupMenu();
		popupMenuMode.removeAll();
		popupMenuMode.setOpaque(false);
		popupMenuMode.setBorder(null);
		model = new DefaultListModel();
		verticalTask = new JList<String>(model);
		verticalTask.setBackground(Color.LIGHT_GRAY);
		verticalTask.addKeyListener(new KeyAdapter() {
			public void keyReleased(KeyEvent ke) {
				if (ke.getKeyCode() == KeyEvent.VK_ENTER){
					insertSelection();
				} 
				if (ke.getKeyCode() == KeyEvent.VK_ESCAPE){
					popupMenu.setVisible(false);
				} 
			}
		});
		verticalTask.addMouseListener(new MouseListener() {
			public void mouseReleased(MouseEvent e) {
				if (e.getClickCount() == 1) {
					insertSelection();
				}
			}

			public void mousePressed(MouseEvent e) {
			}
			public void mouseExited(MouseEvent e) {}

			public void mouseEntered(MouseEvent e) {}

			public void mouseClicked(MouseEvent e) {}
		});
		popupMenu = new JDialog();
		popupMenu.setUndecorated(true);
		popupMenu.setModal(true);

		scrollPaneMenu = new JScrollPane();
		for(Task object: vectorTask){
			String menu = new String(object.getId().toLowerCase());
			model.addElement(menu);
		}
		JMenu endMenuItem =new JMenu("end");
		JMenu startMenuItem =new JMenu("start");
		endMenuItem.addMouseListener(new MouseListener() {
			public void mouseReleased(MouseEvent e) {}

			public void mousePressed(MouseEvent e) {
				if (e.getClickCount() == 1) {
					insertSelectionMode();
				}
			}
			public void mouseExited(MouseEvent e) {}

			public void mouseEntered(MouseEvent e) {}

			public void mouseClicked(MouseEvent e) {}
		});
		endMenuItem.addMenuKeyListener(new MenuKeyListener() {

			public void menuKeyTyped(MenuKeyEvent e) {}

			public void menuKeyReleased(MenuKeyEvent e) {}

			public void menuKeyPressed(MenuKeyEvent e) {
				if (e.getKeyCode() == MenuKeyEvent.VK_ENTER) {
					insertSelectionMode();
				}					
			}
		});
		startMenuItem.addMouseListener(new MouseListener() {
			public void mouseReleased(MouseEvent e) {}

			public void mousePressed(MouseEvent e) {
				if (e.getClickCount() == 1) {
					insertSelectionMode();
				}
			}
			public void mouseExited(MouseEvent e) {}

			public void mouseEntered(MouseEvent e) {}

			public void mouseClicked(MouseEvent e) {}
		});
		startMenuItem.addMenuKeyListener(new MenuKeyListener() {

			public void menuKeyTyped(MenuKeyEvent e) {}

			public void menuKeyReleased(MenuKeyEvent e) {}

			public void menuKeyPressed(MenuKeyEvent e) {
				if (e.getKeyCode() == MenuKeyEvent.VK_ENTER) {
					insertSelectionMode();
				}					
			}
		});
		popupMenuMode.add(startMenuItem);
		popupMenuMode.add(endMenuItem);
		this.newArea.addKeyListener(new KeyListener() {

			public void keyTyped(KeyEvent e) {}

			public void keyReleased(KeyEvent e) {
				if (canShowSuggestion()) {
					final int position = newArea.getCaretPosition();
					Point location;
					try {
						location = newArea.modelToView(position).getLocation();
					} catch (BadLocationException e2) {
						e2.printStackTrace();
						return;
					}
					scrollPaneMenu.getViewport().add(verticalTask);
					popupMenu.add(scrollPaneMenu);
					verticalTask.setFocusable(true);
					popupMenu.setMinimumSize(new Dimension(400,500));
					popupMenu.setMaximumSize(new Dimension(400,500));
					popupMenu.setPreferredSize(new Dimension(400,500));
					verticalTask.setSelectedIndex(0);
					popupMenu.setLocationRelativeTo(newArea);
					popupMenu.setVisible(true);
				}
				if(canShowSuggestionMode()){
					final int position = newArea.getCaretPosition();
					Point location;
					try {
						location = newArea.modelToView(position).getLocation();
					} catch (BadLocationException e2) {
						e2.printStackTrace();
						return;
					}
					popupMenuMode.show(newArea, location.x + 3, location.y + 3);
					newArea.setCaretPosition(position-1);
				}
			}

			private boolean canShowSuggestion() {
				int position = newArea.getCaretPosition();
				String text = newArea.getText();
				if(position<text.length()){
					return (text.charAt(position)== ' ') && (text.charAt(position-1)== ' ') && ((text.charAt(position-2)== '(') || (text.charAt(position-2)== '\\' || (text.charAt(position-2)== '/') || (text.charAt(position-2)== '>')));
				}else{
					return false;
				}	            	
			}

			private boolean canShowSuggestionMode() {
				boolean canShow = false;
				int position = newArea.getCaretPosition();
				String text = newArea.getText();
				if(position>2){
					String input = text.substring(position-2, position-1);
					if(position<text.length()){
						canShow =  (text.charAt(position-1)=='.' && text.charAt(position)==' ');
					}
				}
				return canShow;
			}

			public void keyPressed(KeyEvent e) {}
		});

		this.setMinimumSize(new Dimension(100,50));
		this.setMaximumSize(new Dimension(Integer.MAX_VALUE,50));
		this.newArea.setTransferHandler(new TreeHandler());
		this.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
	}

	public boolean insertSelection() {
		if (verticalTask.getSelectionModel() != null) {
			try {
				String element = ((String)verticalTask.getSelectedValue())+".";
				final int insertionPosition = newArea.getCaretPosition();
				newArea.getDocument().insertString(insertionPosition , element, null);
				popupMenu.setVisible(false);
				newArea.setCaretPosition(insertionPosition +element.length());
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
			return true;
		}
		return false;
	}

	public boolean insertSelectionMode() {
		if (popupMenuMode.getSelectionModel() != null) {
			try {
				boolean isSelected = false;
				int i=0;
				for(i=0;i<popupMenuMode.getComponentCount() && !isSelected;i++){
					isSelected = ((JMenu)popupMenuMode.getSubElements()[i]).isSelected();
				}
				String element = ((JMenu)popupMenuMode.getSubElements()[i-1]).getText();
				int insertionPosition = newArea.getCaretPosition();
				newArea.getDocument().insertString(insertionPosition+1 , element, null);
				newArea.setCaretPosition(newArea.getCaretPosition() + element.length()+1);
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
			popupMenuMode.setVisible(false);
			return true;
		}
		return false;
	}

	public JTextArea getArea(){
		return newArea;
	}

	public JCheckBox getCheckBox(){
		return newCheckArea;
	}

	public JLabel getLabelArea(){
		return newLabelArea;
	}

	public void setActionListener(ActionListener al){
		this.newCheckArea.addActionListener(al);
	}
}

